package com.yy.tech.data.coder.converter;

import com.yy.tech.data.annotation.SecretParam;
import com.yy.tech.data.coder.decode.Decoder;
import com.yy.tech.data.context.DesensitizeContext;
import com.yy.tech.data.context.SecretContent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.Set;

/** decode uri parameter,specify the coder by {@link SecretParam}
 * @author yy
 * @date 2022/4/5
 * @description: TODO
 */
@Component
@ConditionalOnProperty(value = SecretContent.KEY_DESENSITIZE_ENABLE,havingValue = "true")
public class SecretParamGenericConverter implements GenericConverter {

    @Autowired
    private DesensitizeContext context;
    @Override
    public Set<ConvertiblePair> getConvertibleTypes() {
        return Collections.singleton(new ConvertiblePair(String.class, String.class));
    }

    @Override
    public Object convert(final Object obj, final TypeDescriptor source, final TypeDescriptor target) {
        SecretParam secretParam =target.getAnnotation(SecretParam.class);
        if (null != obj && null != secretParam){
            Decoder decoder = getDecoder(secretParam);
            if (null != decoder){
                return decoder.decode(obj);
            }
        }
        return obj;
    }

    private Decoder getDecoder(final SecretParam secret) {
        if (null != secret){
            Class<? extends Decoder> clz = secret.decoder();
            final String name = secret.name();
            if (null != clz){
                return (Decoder) context.getDecoder(clz);
            }else {
                return context.getParamDecoder(name);
            }
        }
        return null;
    }
}
